package com.bawei.lib_log.crash;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;

import androidx.annotation.NonNull;

import com.bawei.lib_log.file.FileManager;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CrashHandler implements Thread.UncaughtExceptionHandler{
    private final String CRASH_LOG_FILE = "crash_log.txt";
    private Context mContext;
    private static CrashHandler sInstance;
    private FileManager fileManager;
    private CrashHandler() {
    }
    public static CrashHandler getInstance() {
        if (sInstance == null) {
            synchronized (CrashHandler.class) {
                if (sInstance == null) {
                    synchronized (CrashHandler.class) {
                        sInstance = new CrashHandler();
                    }
                }
            }
        }
        return sInstance;
    }
    /**
     * 初始化默认异常捕获
     *
     * @param context context
     */
    public void init(Context context) {
        mContext = context;
        fileManager = new FileManager(context);
        // 将此类设为默认异常处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }


    /**
     * 捕获异常
     * @param t the thread
     * @param e the exception
     */
    @Override
    public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
        //异常信息
        String crashInfo = null;
        try {
            crashInfo =  getCrashInfo(t,e);
        } catch (PackageManager.NameNotFoundException ex) {
            throw new RuntimeException(ex);
        }
        //写入文件中：最多10个文件，每个文件不能超过10M
        writeCrashToFile(crashInfo);
        //上传服务器：不能直接上传服务器，因为上传服务器需要网络，如果网络异常，数据丢失
        //开发人员可以查看bug，解决bug，打补丁包热修复

    }

    private void writeCrashToFile(String crashInfo) {
        fileManager.writeDataWithLimits(crashInfo.getBytes());
//        try {
//            File file = new File(Environment.getExternalStorageDirectory(), CRASH_LOG_FILE);
//            FileWriter writer = new FileWriter(file, true);
//            BufferedWriter bufferedWriter = new BufferedWriter(writer);
//            bufferedWriter.write(crashInfo);
//            bufferedWriter.newLine();
//            bufferedWriter.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }

    private String getCrashInfo(Thread thread,  Throwable throwable) throws PackageManager.NameNotFoundException {
        // 示例中只获取了异常的堆栈跟踪信息
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        throwable.printStackTrace(pw);
        pw.flush();
        //时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(new Date());

        //手机信息
        String phoneInfo = "\n" + "************* Phone Info *************" + "\n" + "\n"
                + "Brand: " + android.os.Build.BRAND + "\n" + "\n"
                + "Model: " + android.os.Build.MODEL + "\n" + "\n"
                + "SDK: " + android.os.Build.VERSION.SDK_INT + "\n" + "\n"
                + "************* Phone Info *************" + "\n";
        //版本号版本名称
        PackageManager packageManager = mContext.getPackageManager();
        PackageInfo packageInfo = packageManager.getPackageInfo(mContext.getPackageName(), 0);
        String versionInfo = "\n" + "************* Version Info *************" + "\n" + "\n"
                + "VersionName: " + packageInfo.versionName + "\n" + "\n"
                + "VersionCode: " + packageInfo.versionCode + "\n" + "\n"
                + "************* Version Info *************" + "\n";
        // 可根据需要封装崩溃信息，如线程信息、异常信息、堆栈跟踪等
        String crashInfo = "\n" + "************* Crash Log *************" + "\n" + "\n"
                + "CrashTime: " + time + "\n" + "\n" //时间
                + "Thread: " + thread.getName() + "\n" + "\n" //线程名称
                + "ThreadId: " + thread.getId() + "\n" + "\n" //线程id
                + "Exception: " + throwable.getMessage() + "\n" + "\n" //异常信息
                + "Stack Trace: " +sw+ "\n" + "\n"  //堆栈信息
                + "************* Crash Log *************" + "\n";
        return phoneInfo+versionInfo+crashInfo;

    }
}
